#include "common/configParser.h"
#include "common/cJSON.h"
#include <stdlib.h>
#include <stdio.h>
#include "common/net_config.h"
#include <string.h>

//#include "hal_gps_uv.h"

static void remoteCfgChange(uv_fs_event_t *handle, const char *filename, int32_t events, int32_t status);

#define CAM_SIZE 4
// 相机IP和端口
VzCamInfoStruct *vzArr;
static uint8_t vzNum = 0;

static cJSON *g_json = NULL;
// 车道机配置
static uint8_t CHEDAOJI_NO[CheDaoJi_No_Len];

// 服务器网络配置
static uint8_t REMOTE_SERVER_IP[32] = {0};
static uint16_t REMOTE_SERVER_PORT = 9886;

// 本地网络配置
static uint8_t NET_NAME[16] = {0};
static uint8_t IP[32] = {0};
static uint8_t MASK[32] = {0};
static uint8_t GATEWAY[32] = {0};
static uint32_t STATION_NO = 0;

// wifi配置
static uint8_t WIFI_SSID[64] = {0};
static uint8_t WIFI_PWD[64] = {0};

static QxConfig g_qx_cfg = {0};
static uploadPicConfig g_upload_pic_config = {0};
QxConfig *get_qx_config()
{
  return &g_qx_cfg;
}

uploadPicConfig *get_upload_pic_config()
{
  return &g_upload_pic_config;
}

uint8_t *getWiFiSsid()
{
  return WIFI_SSID;
}

uint8_t *getWiFiPwd()
{
  return WIFI_PWD;
}

uint8_t *getChedaojiNo()
{
  return CHEDAOJI_NO;
}

uint32_t getParkId()
{
  return STATION_NO;
}

VzCamInfoStruct *getCameraInfo()
{
  return vzArr;
}

uint8_t getCameraNum()
{
  return vzNum;
}

uint8_t *getRemoteServIp()
{
  return REMOTE_SERVER_IP;
}

uint16_t getRemoteServPort()
{
  return REMOTE_SERVER_PORT;
}

static int load_hex(char *src, uint8_t dst[])
{
  char buf[128];
  char *p = buf;
  for (; *src; src++)
  {
    if (*src != ' ' && *src != '\t')
      *p++ = *src;
  }
  *p++ = 0;

  int c = 0;
  for (p = buf; *p; p += 2)
  {
    unsigned int val = 0xff;
    int n = sscanf(p, "%02X", &val);
    if (n < 1)
      break;
    dst[c++] = (uint8_t)val;
  }

  return c;
}

void load_cfg()
{
  FILE *fp = fopen("remote_cfg.json", "rb");
  if (!fp)
  {
    LOG_ERROR("remote_cfg.json not found");
    return;
  }

  fseek(fp, 0, SEEK_END);
  unsigned int size = ftell(fp);
  fseek(fp, 0, SEEK_SET);

  char *buf = (char *)malloc(size + 1);
  memset(buf, 0, size + 1);
  fread(buf, size, 1, fp);

  g_json = cJSON_Parse(buf);

  cJSON *json_item;
  cJSON *json_item_ip;
  cJSON *json_item_mask;
  cJSON *json_item_gateway;
  cJSON *json_item_net_name;
  cJSON *json_item_park_id;
  cJSON *json_item_wifi_ssid;
  cJSON *json_item_wifi_pwd;

  cJSON *json_item_CenterServer = cJSON_GetObjectItem(g_json, "CenterServer");
  if (json_item_CenterServer != NULL)
  {
    cJSON *json_item_remote_ip = cJSON_GetObjectItem(json_item_CenterServer, "DataMasterServerIp");
    cJSON *json_item_remote_port = cJSON_GetObjectItem(json_item_CenterServer, "DataMasterServerPort");
    if (json_item_remote_ip != NULL)
    {
      strcpy(REMOTE_SERVER_IP, json_item_remote_ip->valuestring);
    }
    else
    {
      LOG_ERROR("服务器ip字段未设置，请在/opt/Tim/remote_cfg.json设置CenterServer下的DataMasterServerIp字段：");
      goto close_app;
    }
    if (json_item_remote_port != NULL)
    {
      REMOTE_SERVER_PORT = json_item_remote_port->valueint;
    }
    else
    {
      LOG_ERROR("服务器端口字段未设置，请在/opt/Tim/remote_cfg.json设置CenterServer下的DataMasterServerPort字段：");
      goto close_app;
    }
  }
  else
  {
    LOG_ERROR("服务器字段未设置，请在/opt/Tim/remote_cfg.json设置CenterServer字段：");
    goto close_app;
  }

  // 读取具体值
  cJSON *json_laneroad = cJSON_GetObjectItem(g_json, "LaneRoad");
  cJSON *json_array = cJSON_GetArrayItem(json_laneroad, 0);

  json_item = cJSON_GetObjectItem(json_array, "LogicId");
  json_item_ip = cJSON_GetObjectItem(json_array, "Ip");
  json_item_mask = cJSON_GetObjectItem(json_array, "Netmask");
  json_item_gateway = cJSON_GetObjectItem(json_array, "Gateway");
  json_item_net_name = cJSON_GetObjectItem(json_array, "NetName");
  json_item_park_id = cJSON_GetObjectItem(json_array, "ParkId");
  json_item_wifi_ssid = cJSON_GetObjectItem(json_array, "WIFISsid");
  json_item_wifi_pwd = cJSON_GetObjectItem(json_array, "WIFIPwd");

  cJSON *json_item_qx_user = cJSON_GetObjectItem(json_array, "QxUser");
  cJSON *json_item_qx_password = cJSON_GetObjectItem(json_array, "QxPassword");
  cJSON *json_item_service_name = cJSON_GetObjectItem(json_array, "QxServiceName");
  cJSON *json_item_qx_port = cJSON_GetObjectItem(json_array, "QxPort");
  cJSON *json_item_qx_interval = cJSON_GetObjectItem(json_array, "QxReportInterval");
  if (json_item_qx_user == NULL ||
      json_item_qx_password == NULL ||
      json_item_service_name == NULL ||
      json_item_qx_port == NULL ||
      json_item_qx_interval == NULL)
  {
    LOG_ERROR("千寻服务器信息设置不正确，请在/opt/Tim/remote_cfg.json设置'QxUser','QxPassword','QxServiceName','QxPort','QxReportInterval'");
    goto close_app;
  }
  memcpy(g_qx_cfg.qx_user, json_item_qx_user->valuestring, MIN(sizeof(g_qx_cfg.qx_user), strlen(json_item_qx_user->valuestring)));
  memcpy(g_qx_cfg.qx_password, json_item_qx_password->valuestring, MIN(sizeof(g_qx_cfg.qx_password), strlen(json_item_qx_password->valuestring)));
  memcpy(g_qx_cfg.qx_service_name, json_item_service_name->valuestring, MIN(sizeof(g_qx_cfg.qx_service_name), strlen(json_item_service_name->valuestring)));
  g_qx_cfg.qx_port = json_item_qx_port->valueint;
  g_qx_cfg.qx_report_interval = json_item_qx_interval->valueint;
  LOG_INFO("千寻配置，user:%s, password:%s, serviceName:%s, port:%d, interval:%d",
           g_qx_cfg.qx_user, g_qx_cfg.qx_password, g_qx_cfg.qx_service_name,
           g_qx_cfg.qx_port, g_qx_cfg.qx_report_interval);

  cJSON *json_item_upload_pic_speed = cJSON_GetObjectItem(json_array, "UploadSpeed");
  cJSON *json_item_upload_pic_keep_time = cJSON_GetObjectItem(json_array, "UploadKeepTime");
  cJSON *json_item_upload_pic_max_number = cJSON_GetObjectItem(json_array, "UploadPicMaxNumber");
  if (json_item_upload_pic_speed == NULL ||
      json_item_upload_pic_keep_time == NULL ||
      json_item_upload_pic_max_number == NULL)
  {
    LOG_ERROR("上传大图配置设置不正确，请在/opt/Tim/remote_cfg.json设置'UploadSpeed','UploadKeepTime','UploadPicMaxNumber'");
    goto close_app;
  }

  g_upload_pic_config.keep_time = json_item_upload_pic_keep_time->valueint;
  // LOG_INFO("keep_time int-%d,keep_time double-%g", json_item_upload_pic_keep_time->valueint,
  //          json_item_upload_pic_keep_time->valuedouble);

  g_upload_pic_config.speed = json_item_upload_pic_speed->valuedouble;
  // LOG_INFO("speed int-%d,speed double-%g", json_item_upload_pic_speed->valueint,
  //          json_item_upload_pic_speed->valuedouble);
  g_upload_pic_config.max_pic_number = json_item_upload_pic_max_number->valuedouble;

  LOG_INFO("上传大图配置,keep_time:%d,speed:%g, max_pic_number:%d",
           g_upload_pic_config.keep_time, g_upload_pic_config.speed,
           g_upload_pic_config.max_pic_number);

  cJSON *json_item_calibration_delta = cJSON_GetObjectItem(json_array, "CalibrationDelta");
  if (json_item_calibration_delta == NULL)
  {
    LOG_ERROR("标定差值配置设置不正确，请在/opt/Tim/remote_cfg.json设置'CalibrationDelta'");
    goto close_app;
  }
  g_upload_pic_config.calibration_dua = json_item_calibration_delta->valuedouble;

  uint8_t carName[8] = "eth0";
  if (json_item_net_name != NULL)
  {
    memcpy(carName, json_item_net_name->valuestring, strlen(json_item_net_name->valuestring) + 1);
    LOG_INFO("网卡名：%s", carName);
  }
  else
  {
    LOG_ERROR("网卡名未设置，请在/opt/Tim/remote_cfg.json设置NetName字段：");
    goto close_app;
  }

  if (json_item_ip != NULL)
  {
    memcpy(IP, json_item_ip->valuestring, strlen(json_item_ip->valuestring) + 1);
    if (net_set_ifaddr_a(carName, IP) != -1)
    {
      LOG_INFO("设置ip为：%s", IP);
    }
  }
  else
  {
    LOG_ERROR("ip未设置，请在/opt/Tim/remote_cfg.json设置Ip字段：");
    goto close_app;
  }

  if (json_item_mask != NULL)
  {
    memcpy(MASK, json_item_mask->valuestring, strlen(json_item_mask->valuestring) + 1);
    if (net_set_netmask_a(carName, MASK) != -1)
    {
      LOG_INFO("设置子网掩码为：%s", MASK);
    }
  }
  else
  {
    LOG_ERROR("子网掩码未设置，请在/opt/Tim/remote_cfg.json设置Netmask字段：");
    goto close_app;
  }

  if (json_item_gateway != NULL)
  {
    memcpy(GATEWAY, json_item_gateway->valuestring, strlen(json_item_gateway->valuestring) + 1);
    if (net_set_gateway_a(carName, GATEWAY) != -1)
    {
      LOG_INFO("设置网关为：%s", GATEWAY);
    }
  }
  else
  {
    LOG_ERROR("网关未设置，请在/opt/Tim/remote_cfg.json设置Gateway字段：");
    goto close_app;
  }

  if (json_item_wifi_ssid != NULL)
  {
    memcpy(WIFI_SSID, json_item_wifi_ssid->valuestring, strlen(json_item_wifi_ssid->valuestring) + 1);
    LOG_INFO("WIFI ssid: %s", WIFI_SSID);
  }
  else
  {
    LOG_ERROR("Wifi ssid未设置，请在/opt/Tim/remote_cfg.json设置WIFISsid字段：");
    goto close_app;
  }

  if (json_item_wifi_pwd != NULL)
  {
    memcpy(WIFI_PWD, json_item_wifi_pwd->valuestring, strlen(json_item_wifi_pwd->valuestring) + 1);
    LOG_INFO("WIFI pwd: %s", WIFI_PWD);
  }
  else
  {
    LOG_ERROR("Wifi pwd未设置，请在/opt/Tim/remote_cfg.json设置WIFIPwd字段：");
    goto close_app;
  }

  if (json_item_park_id != NULL)
  {
    STATION_NO = json_item_park_id->valueint;
  }
  else
  {
    LOG_ERROR("停车场编号未设置，请在/opt/Tim/remote_cfg.json设置ParkId字段：");
    goto close_app;
  }

  uint8_t mac[6] = {0};
  net_get_hwaddr(carName, mac);
  LOG_INFO("网卡mac地址：%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  memcpy(CHEDAOJI_NO, mac, 6);
  unsigned char logic_ID[6];

  load_hex(json_item->valuestring, logic_ID);
  // LOG_INFO("车道机编号");
  // hzlog_info(userLog, (char *)CHEDAOJI_NO, 6 + n);
  LOG_INFO("车道机逻辑id：logic_ID：%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
           logic_ID[0], logic_ID[1], logic_ID[2], logic_ID[3], logic_ID[4], logic_ID[5]);

  memcpy(CHEDAOJI_NO + 6, logic_ID, 6);

  // 00 00 00 11 11 11 00 00 22 34 56 01
  //  00 14 97 29 1b d0 00 00 22 34 56 83
  //  CHEDAOJI_NO[0] = 0x00;
  //  CHEDAOJI_NO[1] = 0x00;
  //  CHEDAOJI_NO[2] = 0x00;
  //  CHEDAOJI_NO[3] = 0x11;
  //  CHEDAOJI_NO[4] = 0x11;
  //  CHEDAOJI_NO[5] = 0x11;
  //  CHEDAOJI_NO[6] = 0x00;
  //  CHEDAOJI_NO[7] = 0x00;
  //  CHEDAOJI_NO[8] = 0x22;
  //  CHEDAOJI_NO[9] = 0x34;
  //  CHEDAOJI_NO[10] = 0x56;
  //  CHEDAOJI_NO[11] = 0x00;

  LOG_INFO("车道机编号:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
           CHEDAOJI_NO[0], CHEDAOJI_NO[1], CHEDAOJI_NO[2], CHEDAOJI_NO[3], CHEDAOJI_NO[4], CHEDAOJI_NO[5],
           CHEDAOJI_NO[6], CHEDAOJI_NO[7], CHEDAOJI_NO[8], CHEDAOJI_NO[9], CHEDAOJI_NO[10], CHEDAOJI_NO[11]);

  // 摄像头配置
  json_item = cJSON_GetObjectItem(json_array, "VideoRecognition");
  json_item = cJSON_GetObjectItem(json_item, "VRCamera");
  int32_t camSize = cJSON_GetArraySize(json_item);
  if (camSize <= 0)
  {
    LOG_ERROR("VRCamera下数组为0，请在/opt/Tim/remote_cfg.json设置VRCamera相关字段：");
    goto close_app;
  }
  vzNum = camSize;
  LOG_INFO("camSize:%d", camSize);
  vzArr = (VzCamInfoStruct *)malloc(camSize * sizeof(VzCamInfoStruct));
  memset(vzArr, 0x0, sizeof(camSize * sizeof(VzCamInfoStruct)));
  uint8_t cam_index = 0;

  cJSON *json_cam = NULL;
  cJSON *json_cam_ip = NULL;
  cJSON *json_cam_id = NULL;
  cJSON *json_cam_port = NULL;
  cJSON *json_cam_remark = NULL;
  cJSON *json_cam_calibration = NULL;

  bool atLeastOneHasCalibration = false;
  cJSON_ArrayForEach(json_cam, json_item)
  {
    json_cam_id = cJSON_GetObjectItem(json_cam, "Id");
    uint8_t cam_id = 0;
    if (json_cam_id != NULL)
    {
      vzArr[cam_index].VZ_ID = cam_id = json_cam_id->valueint;
    }
    else
    {
      LOG_ERROR("摄像头Id字段未设置，请在/opt/Tim/remote_cfg.json设置VRCamera相关字段：");
      goto close_app;
    }

    json_cam_ip = cJSON_GetObjectItem(json_cam, "IP");
    if (json_cam_ip != NULL)
    {
      strcpy(vzArr[cam_index].VZ_CAM_IP, json_cam_ip->valuestring);
    }
    else
    {
      LOG_ERROR("摄像头[Id:%d]ip字段未设置，请在/opt/Tim/remote_cfg.json设置VRCamera相关字段：", cam_id);
      goto close_app;
    }

    json_cam_port = cJSON_GetObjectItem(json_cam, "Port");
    if (json_cam_port != NULL)
    {
      vzArr[cam_index].VZ_CAM_PORT = json_cam_port->valueint;
    }
    else
    {
      LOG_ERROR("摄像头[Id:%d]port字段未设置，请在/opt/Tim/remote_cfg.json设置VRCamera相关字段：", cam_id);
      goto close_app;
    }

    json_cam_remark = cJSON_GetObjectItem(json_cam, "Remark");
    if (json_cam_remark != NULL)
    {
      memset(vzArr[cam_index].remark, 0, MEM_SIZE(VzCamInfoStruct, remark));
      strcpy(vzArr[cam_index].remark, json_cam_remark->valuestring);
    }
    else
    {
      LOG_ERROR("摄像头[Id:%d]remark字段未设置，请在/opt/Tim/remote_cfg.json设置VRCamera相关字段：", cam_id);
      goto close_app;
    }

    json_cam_calibration = cJSON_GetObjectItem(json_cam, "Calibration");
    if (json_cam_calibration != NULL)
    {
      atLeastOneHasCalibration = true;
      vzArr[cam_index].CALIBRATION = json_cam_calibration->valueint;
    }
    else
    {
      vzArr[cam_index].CALIBRATION = 0;
    }
    LOG_INFO("vzArr[%d].CALIBRATION:%d", cam_index, vzArr[cam_index].CALIBRATION);

    cam_index++;
  }

  if (atLeastOneHasCalibration == false)
  {
    LOG_ERROR("摄像头Calibration字段未设置，请在/opt/Tim/remote_cfg.json设置Calibration相关字段（至少设置一个相机作为标定相机）");
    goto close_app;
  }

  cJSON_Delete(g_json);
  free(buf);
  fclose(fp);

  startWatchRemoteCfg();
  return;
close_app:
  LOG_ERROR("例子：");
  LOG_ERROR("# 远程服务器相关设置");
  LOG_ERROR("\"CenterServer\": {");
  LOG_ERROR("       ...");
  LOG_ERROR("       \"DataMasterServerIp\":\"47.113.112.188\"");
  LOG_ERROR("       \"DataMasterServerPort\":9886");
  LOG_ERROR("       ...");
  LOG_ERROR(" },");
  LOG_ERROR("\"LaneRoad\": [");
  LOG_ERROR("   {");
  LOG_ERROR("       ...");
  LOG_ERROR("       # 停车场编号");
  LOG_ERROR("       \"ParkId\":1000480");
  LOG_ERROR("       # 本地网络以及逻辑号相关设置");
  LOG_ERROR("       \"LogicId\":\"ff ff 12 34 56 78\"");
  LOG_ERROR("       \"NetName\":\"eth0\"");
  LOG_ERROR("       \"Ip\":\"192.168.2.129\"");
  LOG_ERROR("       \"Netmask\":\"255.255.255.0\"");
  LOG_ERROR("       \"Gateway\":\"192.168.2.1\"");
  LOG_ERROR("       \"WifiSsid\":\"Zxlxf\"");
  LOG_ERROR("       \"WifiPwd\":\"1234567890\"");
  LOG_ERROR("       # 千寻服务相关配置");
  LOG_ERROR("       \"QxUser\":\"qxwone003\"");
  LOG_ERROR("       \"QxPassword\":\"769a5c1\"");
  LOG_ERROR("       \"QxPort\":8002");
  LOG_ERROR("       \"QxServiceName\":\"rtd.ntrip.qxwz.com\"");
  LOG_ERROR("       \"QxReportInterval\":1");
  LOG_ERROR("       # 大图上传相关配置");
  LOG_ERROR("       \"UploadSpeed\":0.2");
  LOG_ERROR("       \"UploadKeepTime\":15");
  LOG_ERROR("       \"UploadPicMaxNumber\":500");
  LOG_ERROR("       # 标定相关配置");
  LOG_ERROR("       \"CalibrationDelta\":0.000015");
  LOG_ERROR("       # 摄像头相关配置");
  LOG_ERROR("       \"VideoRecognition\":{");
  LOG_ERROR("           \"VRCamera\":[");
  LOG_ERROR("               {");
  LOG_ERROR("                   \"Id\": 1");
  LOG_ERROR("                   \"IP\":\"192.168.2.146\"");
  LOG_ERROR("                   \"Port\":8131");
  LOG_ERROR("                   \"Remark\":\"前/中/后摄像\"");
  LOG_ERROR("                   # 1代表该相机参与标定，目前只支持一个相机标定");
  LOG_ERROR("                   \"Calibration\": 1");
  LOG_ERROR("               }");
  LOG_ERROR("       ...");
  LOG_ERROR("   }");
  LOG_ERROR("]");
  exit(-1);
}

void startWatchRemoteCfg()
{
  LOG_NOTICE("监视/opt/Tim/remote_cfg.json文件，修改该文件会让Tim重启");
  uv_loop_t *loop = getLoop();
  uv_fs_event_t *fs_event_req = malloc(sizeof(uv_fs_event_t));
  uv_fs_event_init(loop, fs_event_req);
  uv_fs_event_start(fs_event_req, remoteCfgChange, "remote_cfg.json", UV_FS_EVENT_RECURSIVE);
}

static void remoteCfgChange(uv_fs_event_t *handle, const char *filename, int32_t events, int32_t status)
{
  uint8_t path[1024];
  size_t size = 1023;
  uv_fs_event_getpath(handle, path, &size);
  path[size] = '\0';

  if (events & UV_CHANGE)
  {
    LOG_INFO("文件 %s 被修改，重新启动程序", path);
    // 这个命令只在开发板上生效
    system("kill `ps -ef |  grep -E ./Tim$ | awk '{print $1}' | awk 'NR==1{print}'` && sh /opt/Tim/start.sh");
  }
}